package utils

import (
	"errors"
	"fmt"
	"strings"
	"time"
)

// TimeNowFormat 日期时间格式化
//
// 参数
//
//	layout: 格式化字符串，比如"20060102150405"，"20060102150405.000"，"2006-01-02 15:04:05.000"
//
// 返回值：
//
//	格式化后的日期时间
func TimeNowFormat(layout string) string {
	nowTime := time.Now().In(time.Local)
	if layout == "" {
		return nowTime.Format("20060102150405")
	} else if layout == "20060102150405.000" {
		withDot := nowTime.Format("20060102150405.000")
		return strings.Replace(withDot, ".", "", 1)
	}
	return nowTime.Format(layout)
}

func FormatTimeRange(beginStr, endStr string) (time.Time, time.Time, error) {
	begin, err1 := time.Parse(time.DateTime, beginStr)
	end, err2 := time.Parse(time.DateTime, endStr)

	if err1 != nil || err2 != nil {
		return time.Time{}, time.Time{}, errors.New("时间格式错误")
	}
	return begin, end, nil
}

// ParseTimeRange 格式化的日期时间范围为time.Time格式，自动判断时间格式，
// 如果是日期并且设置开始为yyyy-MM-dd 00:00:00，结束时间为 yyyy-MM-dd 23:59:59.999
// 如果是yyyy-MM-dd HH:mm:ss格式，则直接格式化
//
// 参数
//
//	beginStr: 开始时间，"2006-01-02"，"2006-01-02 15:04:05"
//	endStr: 截止时间，"2006-01-02"，"2006-01-02 15:04:05"
//
// 返回值：
//
//	time.Time: 开始时间
//	time.Time: 截止时间
//	error: 错误
func ParseTimeRange(beginStr, endStr string) (time.Time, time.Time, error) {
	// 支持两种时间格式
	tryParse := func(s string) (time.Time, bool, error) {
		// 尝试解析为日期时间格式，兼容当前系统时区
		if t, err := time.ParseInLocation(time.DateTime, s, time.Local); err == nil {
			return t, false, nil // 非纯日期格式
		}
		// 尝试解析为纯日期格式，兼容当前系统时区
		if t, err := time.ParseInLocation(time.DateOnly, s, time.Local); err == nil {
			return t, true, nil // 纯日期格式
		}
		return time.Time{}, false, fmt.Errorf("无法识别的时间格式: %s", s)
	}

	begin, isBeginDateOnly, err := tryParse(beginStr)
	if err != nil {
		return time.Time{}, time.Time{}, fmt.Errorf("开始时间格式错误: %w", err)
	}

	end, isEndDateOnly, err := tryParse(endStr)
	if err != nil {
		return time.Time{}, time.Time{}, fmt.Errorf("结束时间格式错误: %w", err)
	}

	// 校验开始时间不能晚于结束时间
	if begin.After(end) {
		return time.Time{}, time.Time{}, errors.New("开始时间不能晚于结束时间")
	}

	// 如果两者都是日期，转换为00:00:00 ~ 23:59:59.999
	if isBeginDateOnly && isEndDateOnly {
		begin = time.Date(begin.Year(), begin.Month(), begin.Day(), 0, 0, 0, 0, begin.Location())
		end = time.Date(end.Year(), end.Month(), end.Day(), 23, 59, 59, int(time.Second-time.Nanosecond), end.Location())
	}

	return begin, end, nil
}
